from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
from typing import List, Dict, Any, Optional
from models.commit_message_model_workflow import CommitMessageModelWorkflow
from rag.rag_system_workflow import RAGSystemWorkflow
from monitoring.decorators import monitor_api_endpoint, monitor_rag_query, monitor_model_generation
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter()

# 初始化工作流模型
commit_model_workflow = CommitMessageModelWorkflow()
rag_system_workflow = RAGSystemWorkflow()

# 请求和响应模型 - 保持与原有API一致
class SummaryItem(BaseModel):
    order: int
    summary: str

class SummarizeRequest(BaseModel):
    summaries: List[SummaryItem]
    user_id: Optional[str] = None
    session_id: Optional[str] = None

class SummarizeResponse(BaseModel):
    result: str
    commit_count: int
    files_affected: int
    change_types: List[str]
    model_used: str
    timestamp: str
    workflow_steps: int = 0  # 新增：工作流步骤数

class RAGQuestionRequest(BaseModel):
    question: str
    collection_name: str = "default"
    top_k: Optional[int] = None
    rerank_threshold: Optional[float] = None

class RAGQuestionResponse(BaseModel):
    status: str
    question: str
    answer: str
    sources: List[Dict[str, str]]
    context_length: int
    documents_retrieved: int
    documents_used: int
    workflow_steps: int = 0  # 新增：工作流步骤数

class WorkflowInfoResponse(BaseModel):
    workflow_type: str
    model_name: str
    workflow_steps: List[str]
    execution_trace: bool = False

# 生成汇总commit message路由 - 使用工作流版本
@router.post("/workflow/summarize", response_model=SummarizeResponse)
@monitor_api_endpoint("workflow_summarize")
@monitor_model_generation("commit_message_workflow")
async def summarize_commits_workflow(
    request: SummarizeRequest,
    user_id: Optional[str] = Query(None, description="用户ID，用于追踪（URL参数）"),
    session_id: Optional[str] = Query(None, description="会话ID，用于追踪（URL参数）")
):
    """根据多个summary信息生成一条汇总的commit message - 使用LangGraph工作流"""
    try:
        # 优先使用请求体中的参数，如果没有则使用URL参数
        final_user_id = request.user_id or user_id
        final_session_id = request.session_id or session_id
        
        # 打印请求参数
        logger.info("=== 收到工作流汇总请求 ===")
        logger.info(f"追踪参数 - user_id: {final_user_id}, session_id: {final_session_id}")
        logger.info(f"请求体: {request}")
        logger.info(f"summaries数量: {len(request.summaries)}")
        
        for i, summary in enumerate(request.summaries):
            logger.info(f"Summary {i+1}: order={summary.order}, content='{summary.summary}'")
        
        # 转换为字典格式
        summaries_dict = [{"order": item.order, "summary": item.summary} for item in request.summaries]
        logger.info(f"转换后的数据: {summaries_dict}")
        
        # 调用工作流模型生成结果，传递追踪参数
        logger.info("开始使用工作流生成汇总commit message...")
        result = commit_model_workflow.generate_structured_summary(
            summaries_dict,
            user_id=final_user_id,
            session_id=final_session_id
        )
        
        logger.info("=== 工作流生成结果 ===")
        logger.info(f"生成的commit message: {result.get('result', 'N/A')}")
        logger.info(f"变更类型: {result.get('change_types', [])}")
        logger.info(f"影响文件数: {result.get('files_affected', 0)}")
        
        # 添加工作流步骤信息
        if "workflow_steps" not in result:
            result["workflow_steps"] = 6  # 默认步骤数
        
        return SummarizeResponse(**result)
    except Exception as e:
        logger.error(f"工作流生成汇总commit message失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"工作流生成汇总commit message失败: {str(e)}")

# RAG问答路由 - 使用工作流版本
@router.post("/workflow/rag/ask", response_model=RAGQuestionResponse)
@monitor_api_endpoint("workflow_rag_ask")
@monitor_rag_query()
async def ask_question_workflow(request: RAGQuestionRequest):
    """基于RAG工作流回答问题"""
    try:
        logger.info(f"收到工作流RAG问题: {request.question}")
        
        # 调用工作流RAG系统
        result = rag_system_workflow.ask_question(
            question=request.question,
            collection_name=request.collection_name,
            top_k=request.top_k,
            rerank_threshold=request.rerank_threshold
        )
        
        logger.info(f"工作流RAG回答完成: {request.question}")
        
        # 确保返回结果包含所有必需字段
        if result.get("status") == "error":
            # 错误情况下返回默认值
            return RAGQuestionResponse(
                status="error",
                question=request.question,
                answer=result.get("message", "处理失败"),
                sources=[],
                context_length=0,
                documents_retrieved=0,
                documents_used=0,
                workflow_steps=6
            )
        
        # 添加工作流步骤信息
        if "workflow_steps" not in result:
            result["workflow_steps"] = 6  # 默认步骤数
        
        return RAGQuestionResponse(**result)
    except Exception as e:
        logger.error(f"工作流RAG问答失败: {str(e)}")
        # 异常情况下返回默认响应
        return RAGQuestionResponse(
            status="error",
            question=request.question,
            answer=f"工作流RAG问答失败: {str(e)}",
            sources=[],
            context_length=0,
            documents_retrieved=0,
            documents_used=0,
            workflow_steps=6
        )

# 工作流信息路由
@router.get("/workflow/info", response_model=WorkflowInfoResponse)
@monitor_api_endpoint("workflow_get_info")
async def get_workflow_info():
    """获取工作流信息"""
    try:
        commit_workflow_info = commit_model_workflow.get_workflow_info()
        rag_workflow_info = rag_system_workflow.get_workflow_info()
        
        return WorkflowInfoResponse(
            workflow_type="LangGraph",
            model_name=commit_workflow_info["model_name"],
            workflow_steps=commit_workflow_info["workflow_steps"],
            execution_trace=True
        )
    except Exception as e:
        logger.error(f"获取工作流信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取工作流信息失败: {str(e)}")

# 工作流追踪路由
@router.post("/workflow/trace/summarize")
@monitor_api_endpoint("workflow_trace_summarize")
@monitor_model_generation("commit_message_workflow_trace")
async def trace_summarize_workflow(request: SummarizeRequest):
    """追踪工作流执行过程"""
    try:
        summaries_dict = [{"order": item.order, "summary": item.summary} for item in request.summaries]
        
        # 使用追踪模式运行工作流
        result = commit_model_workflow.run_workflow_with_tracing(summaries_dict)
        
        return {
            "status": "success",
            "trace_result": result
        }
    except Exception as e:
        logger.error(f"工作流追踪失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"工作流追踪失败: {str(e)}")

@router.post("/workflow/trace/rag")
@monitor_api_endpoint("workflow_trace_rag")
@monitor_rag_query()
async def trace_rag_workflow(request: RAGQuestionRequest):
    """追踪RAG工作流执行过程"""
    try:
        # 使用追踪模式运行RAG工作流
        result = rag_system_workflow.run_workflow_with_tracing(
            question=request.question,
            collection_name=request.collection_name,
            top_k=request.top_k,
            rerank_threshold=request.rerank_threshold
        )
        
        return {
            "status": "success",
            "trace_result": result
        }
    except Exception as e:
        logger.error(f"RAG工作流追踪失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"RAG工作流追踪失败: {str(e)}")

# 健康检查
@router.get("/workflow/health")
@monitor_api_endpoint("workflow_health_check")
async def workflow_health_check():
    """工作流健康检查"""
    logger.info("收到工作流健康检查请求")
    return {
        "status": "healthy",
        "service": "LangGraph Workflow Service",
        "models": {
            "commit_model": commit_model_workflow.model_name,
            "rag_system": "RAGSystemWorkflow"
        },
        "workflow_enabled": True
    } 